package cn.com.godliu.rabbitmqprovider.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class TopicRabbitConfig {

    //绑定键
    public final static String man = "man.#";
    public final static String woman = "woman";
    public final static String both = "both";
    //死信队列名称
    public final static String dead_letter = "deadletter";
    //死信交换机名称
    final static String deal_exchangeName = "dealExchange";
    //死信 routingKey
    final static String dead_RoutingKey = "deadroutingkey";
    //死信队列 交换机标识符
    public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
    //死信队列交换机绑定键标识符
    public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";

    /**
     * 主题交换机，这个交换机其实跟直连交换机流程差不多，但是它的特点就是在它的路由键和绑定键之间是有规则的。
     * 简单地介绍下规则：
     *
     *  * (星号) 用来表示一个单词 (必须出现的)
     *  # (井号) 用来表示任意数量（零个或多个）单词
     */

    /**
     * 创建一个TTL队列，当10秒未消费消息进入死信，可以通过创建消息进行测试
     *
     * @return
     */
    @Bean
    public Queue firstQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-message-ttl", 10000); //设置10S未消费进入死信队列
        args.put("x-dead-letter-exchange", deal_exchangeName);//设置死信交换机
        args.put("x-dead-letter-routing-key", dead_RoutingKey);//设置死信路由key
        return QueueBuilder.durable(TopicRabbitConfig.man).withArguments(args).build();
        //return new Queue(TopicRabbitConfig.man,true,false,false,args);
    }

    @Bean
    public Queue secondQueue() {
        return new Queue(TopicRabbitConfig.woman);
    }

    @Bean
    public Queue thirdQueue() {
        return new Queue(TopicRabbitConfig.both);
    }

    @Bean
    TopicExchange exchange() {
        return new TopicExchange("topicExchange");
    }


    //创建配置死信邮件队列dead_letter
    @Bean
    public Queue deadQueue() {
        return QueueBuilder.durable(TopicRabbitConfig.dead_letter).build();
    }

    //创建死信交换机
    @Bean
    public DirectExchange deadExchange() {
        return new DirectExchange(deal_exchangeName, true, false);
    }

    //死信队列与死信交换机绑定
    @Bean
    public Binding bindingDeadExchange() {
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with(dead_RoutingKey);
    }


    //将firstQueue和topicExchange绑定,而且绑定的键值为topic.man
    //这样只要是消息携带的路由键是topic.man,才会分发到该队列
    @Bean
    Binding bindingExchangeMessage() {
        return BindingBuilder.bind(firstQueue()).to(exchange()).with(man);
    }

    //将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
    // 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列
    @Bean
    Binding bindingExchangeMessage2() {
        return BindingBuilder.bind(secondQueue()).to(exchange()).with(woman);
    }

    //将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
    // 这样只要是消息携带的路由键存在topic,都会分发到该队列
    @Bean
    Binding bindingExchangeMessage3() {
        return BindingBuilder.bind(thirdQueue()).to(exchange()).with(both);
    }

}
